package com.jcf.springboot.common.config;

import com.jcf.springboot.common.handler.AuthHandshakeInterceptor;
import com.jcf.springboot.security.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * @author ${chaofan.ji}
 * @since 2025/4/17
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

  @Autowired
  private JwtUtil jwtUtil;
  @Autowired
  private UserDetailsService userDetailsService;
  @Autowired
  private AuthHandshakeInterceptor authHandshakeInterceptor;

  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/ws").setAllowedOrigins("*").addInterceptors(authHandshakeInterceptor);
  }

  @Override
  public void configureClientInboundChannel(ChannelRegistration registration) {
    registration.interceptors(new ChannelInterceptor() {
      @Override
      public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if(StompCommand.CONNECT.equals(accessor.getCommand())){
          String token = accessor.getFirstNativeHeader("token");
          if(!StringUtils.isEmpty(token)){
            Claims claimByToken = jwtUtil.getClaimByToken(token);
            String username = claimByToken.getSubject();
            if(!StringUtils.isEmpty(username)){
              UserDetails userDetails = userDetailsService.loadUserByUsername(username);
              if(jwtUtil.validateJWT(token).getSuccess()){
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                accessor.setUser(usernamePasswordAuthenticationToken);
                System.out.println("+++++++++++++"+Thread.currentThread().getName());
              }
            }
          }

        }
        return message;
      }

    });
  }

  @Override
  public void configureMessageBroker(MessageBrokerRegistry registry) {
//    registry.enableSimpleBroker("/queue");
    registry.enableSimpleBroker("/topic","/queue");
    registry.setApplicationDestinationPrefixes("/app");
    registry.setUserDestinationPrefix("/user");
  }
}
